/**
 * Baijiahulian.com Inc. Copyright (c) 2014-2016 All Rights Reserved.
 */
package com.baijia.authentication.principal.populator;

import com.baijia.authentication.AccountType;
import com.baijia.authentication.Authentication;
import com.baijia.authentication.AuthenticationMetaDataPopulator;
import com.baijia.authentication.principal.Credentials;
import com.baijia.authentication.principal.credentials.PassportCredentials;
import com.baijia.authentication.principal.credentials.UserCredentials;
import com.baijia.dao.OrgAccountDao;
import com.baijia.dao.OrgCascadeAccountDao;
import com.baijia.dao.PassportDao;
import com.baijia.dao.UserDao;
import com.baijia.dao.po.OrgAccount;
import com.baijia.dao.po.OrgCascadeAccount;
import com.baijia.dao.po.Passport;
import com.baijia.dao.po.User;
import com.baijia.util.JacksonUtil;
import com.baijia.util.JigouPasswordUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import static com.baijia.authentication.AccountType.ORG;

/**
 * @desc 补充authentication信息，从credentials获得 Created by dudu on 16/4/26.
 */
@Component
public class PassportMetaDataPopulator implements AuthenticationMetaDataPopulator {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PassportDao passportDao;

    @Autowired
    private OrgAccountDao orgAccountDao;

    @Autowired
    private OrgCascadeAccountDao orgCascadeAccountDao;

    @Autowired
    private UserDao userDao;

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.baijia.authentication.AuthenticationMetaDataPopulator#populateAttributes(com.baijia.authentication.Authentication
     * , com.baijia.authentication.principal.Credentials)
     */
    @Override
    public Authentication populateAttributes(Authentication authentication, Credentials credentials) {
        PassportCredentials passportCredentials = (PassportCredentials) credentials;
        String mobile = passportCredentials.getUsername();
        Integer appId = passportCredentials.getAccountType();
        AccountType accountType = AccountType.getAccountTypeByCode(appId);
        switch (accountType) {
            case ORG:
                OrgAccount orgAccount = orgAccountDao.findByMobile(mobile, passportCredentials.getCountryCode());
                if (orgAccount != null) {
                    authentication.getAttributes().put(ACCOUNT_ID, orgAccount.getId());
                    authentication.getAttributes().put(ACCOUNT_NUMBER, orgAccount.getNumber());
                    try {
                        orgAccount.setPassword(null);
                        authentication.getAttributes().put(ORG_ACCOUNT, JacksonUtil.obj2Str(orgAccount));
                    } catch (IOException e) {
                        logger.error("save orgAccount into dession error!", e);
                    }
                }
                break;
            case ORG_SUB_ACCT:
                OrgCascadeAccount orgCascadeAccount = orgCascadeAccountDao.findByUsername(mobile);
                if (orgCascadeAccount != null) {
                    orgAccount = orgAccountDao.getById(orgCascadeAccount.getOrgId());
                    authentication.getAttributes().put(ACCOUNT_ID, orgAccount.getId());
                    authentication.getAttributes().put(ACCOUNT_NUMBER, orgAccount.getNumber());
                    authentication.getAttributes().put(ORG_CASCADE_ACCOUNTID, orgCascadeAccount.getId());
                    try {
                        authentication.getAttributes().put(ORG_ACCOUNT, JacksonUtil.obj2Str(orgAccount));
                        authentication.getAttributes().put(ORG_CASCADE_ACCOUNT, JacksonUtil.obj2Str(orgCascadeAccount));
                        orgAccount.setPassword(null);
                        orgCascadeAccount.setPassword(null);
                    } catch (IOException e) {
                        logger.error("save orgCascadeAccount into dession error!", e);
                    }
                }
                break;
            case USER:
            case ORG_TEACHER:
                User user = userDao.getUserByMobile(mobile);
                if (user != null) {
                    authentication.getAttributes().put(ACCOUNT_ID, user.getId());
                    authentication.getAttributes().put(ACCOUNT_NUMBER, user.getNumber());
                    authentication.getAttributes().put(ACCOUNT_MOBILE, user.getMobile());
                    try {
                        user.setPassword(null);
                        authentication.getAttributes().put(USER, JacksonUtil.obj2Str(user));
                    } catch (IOException e) {
                        logger.error("save user into dession error!", e);
                    }
                }
                break;
            case MOBILE:
                authentication.getAttributes().put(ACCOUNT_MOBILE, credentials.getUsername());
                break;
            default:
                Passport passport = passportDao.findByMobile(mobile);
                if (passport != null) {
                    authentication.getAttributes().put(PASSPORT_ID, passport.getId());
                }
                break;
        }

        return authentication;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.baijia.authentication.AuthenticationMetaDataPopulator#supports(com.baijia.authentication.principal.Credentials
     * )
     */
    @Override
    public boolean supports(Credentials credentials) {
        return credentials instanceof PassportCredentials;
    }
}
